#include <bits/stdc++.h>

#define in read()
#define fi first
#define se second
#define pb push_back
#define rep(i, x, y) for(int i = (x); i <= (y); i++)
#define per(i, x, y) for(int i = (x); i >= (y); i--)

using namespace std;

typedef long long ll;
typedef double db;
typedef vector < int > vec;
typedef pair < int , int > pii;

int read() {
    int x = 0; bool f = 0; char ch = getchar(); while(!isdigit(ch)) f |= ch == '-',ch = getchar();
    while(isdigit(ch)) x = x * 10 + (ch ^ 48),ch = getchar(); return f ? -x : x;
}

const int N = 110;
const int inf = 0x3f3f3f3f;

char s[N][N];
int sx, sy, tx, ty, lidh[N], ridh[N], lidl[N], ridl[N], lid[N][N], rid[N][N], n, m, tot;

namespace F {
	const int N = 110 * 110;
	const int M = N * 10;
	struct edge { int v, w, nxt; } e[M << 1];
	int h[N], cnt = 1, now[N], d[N], S, T;
	void tlink(int x, int y, int w) { e[++cnt] = (edge) { y, w, h[x] }; h[x] = cnt; }
	void link(int x, int y, int w) { tlink(x, y, w); tlink(y, x, 0); }
	void setst(int x, int y) { S = x; T = y; }
	bool bfs() {
		queue < int > q; rep(i, 0, tot) d[i] = 0; d[S] = 1; q.push(S); now[S] = h[S];
		while(!q.empty()) {
			int x = q.front(); q.pop();// cerr << x << endl;
			for(int i = h[x], y; i; i = e[i].nxt)
				if(e[i].w && !d[y = e[i].v]) {
					d[y] = d[x] + 1; now[y] = h[y]; q.push(y); if(y == T) return true;
				}
		} return false;
	}
	int dfs(int x, int flow) {
		if(x == T) return flow;
		int res = flow; 
		for(int i = now[x], y; i && res; i = e[i].nxt) {
			now[x] = i;
			if(e[i].w && d[y = e[i].v] == d[x] + 1) {
				int k = dfs(y, min(res, e[i].w));
				e[i].w -= k; e[i ^ 1].w += k; res -= k;
			}
		} return flow - res;
	}
	ll mxflow;
	ll runit() {
		mxflow = 0; int flow; while(bfs()) while(flow = dfs(S, inf)) mxflow += flow; return mxflow;
	}
}

int main() {
#ifndef ONLINE_JUDGE
    freopen("1.in","r",stdin);
#endif
    n = in, m = in;
	rep(i, 1, n) scanf("%s", s[i] + 1);
	rep(i, 1, n) {
		rep(j, 1, m) {
			if(s[i][j] == 'S') sx = i, sy = j;
			if(s[i][j] == 'T') tx = i, ty = j;
		}
	}
	if(sx == tx || sy == ty) return puts("-1"), 0;
	rep(i, 1, n) lidh[i] = ++tot;
	rep(i, 1, m) lidl[i] = ++tot;
	rep(i, 1, n) rep(j, 1, m) if(s[i][j] != '.') lid[i][j] = ++tot, rid[i][j] = ++tot, F :: link(lid[i][j], rid[i][j], (s[i][j] == 'o' ? 1 : inf));
	rep(i, 1, n) 
		rep(j, 1, m) if(lid[i][j]) F :: link(lidh[i], lid[i][j], inf), F :: link(rid[i][j], lidh[i], inf);
	rep(j, 1, m) 
		rep(i, 1, n) if(lid[i][j]) F :: link(lidl[j], lid[i][j], inf), F :: link(rid[i][j], lidl[j], inf);
	F :: setst(lid[sx][sy], rid[tx][ty]);
	cout << F :: runit() << endl; return 0;
}
